--[[------------------------------------------
Author: lichanghai
CreateDate: 2019-08-06
$Id: class.lua 522875 2022-01-27 09:45:52Z lupulin $
Brief: 基础类库
------------------------------------------]]--

--获取一个class的父类
function Super(cls)
	return getmetatable(cls).__index
end

--判断一个class或者对象是否
function IsSub(clsOrObj, Ancestor)
	local cur = clsOrObj
	while  1 do
		local mt = getmetatable(cur)
		if mt then
			cur = mt.__index
			if cur == Ancestor then
				return true
			end
		else
			return false
		end
	end
end

function ToString(t)
    local msg = "<<" .. t.__ClassType .. ">>"
    if t.ToString then msg = msg .. t:ToString() end
    return msg
end

--暂时没有一个比较好的方法来防止将Class的table当成一个实例来使用
--大家命名一个Class的时候一定要和其产生的实例区别开来。
clsObject = {
    --用于区别是否是一个对象 or Class or 普通table
    __ClassType = "<base class>"
}

function clsObject:Inherit(clsName, cls)
	cls = cls or {}
	cls.mt = {
        __index = cls,
        __tostring = ToString,
    }
	assert(clsName,"must have clsName")
	cls.__ClassType = clsName
	cls.__InheritMap = { [self:GetType()] = true }  -- 记录继承类型
	cls.__InheritSelf = false
	if self.__InheritMap then
		for UpType, _ in pairs(self.__InheritMap) do
			cls.__InheritMap[UpType] = true
		end
	end
	--没有对table属性做深拷贝，如果这个类有table属性应该在init函数中初始化
	--不应该把一个table属性放到class的定义中

	setmetatable(cls, { __index = self})
	return cls
end

function clsObject:IsSubObj(ObjType)
	return self:GetTypeMap()[ObjType]
end

function clsObject:GetTypeMap()
	local mt = getmetatable(self)
	if mt then
		local cls = mt.__index
		if not cls.__InheritSelf then
			cls.__InheritMap[cls:GetType()] = true
			cls.__InheritSelf = true
		end
		return cls.__InheritMap
	end
	return {}
end

function clsObject:New(...)
	local obj = {}

	--没有初始化对象的属性，对象属性应该在init函数中显示初始化
	--如果是子类，应该在自己的init函数中先调用父类的init函数
	setmetatable(obj, self.mt)

	if obj.__init__ then
		obj:__init__(...)
	end

	if GC and GC.OnObjNew then
		GC:OnObjNew(obj)
	end
	return obj
end

function clsObject:__init__()
	--nothing
end

function clsObject:IsClass()
	return true
end

function clsObject:OnCreate()
    self.__Destroy = nil
end

function clsObject:OnDestroy()
	--所有对象释放的时候删除callout
	CALLOUT.RemoveAll(self)
    self.__Destroy = true
end

function clsObject:GetType()
	return self.__ClassType
end
